/**
 * @file ActionResource.java
 * @author ApertureScience
 */
package aperturescience.resources;
import java.io.IOException;

import org.json.JSONException;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.Put;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;

import aperturescience.types.Action;
import aperturescience.types.JSONMessageResponse;
import aperturescience.wargames.WarGamesApplication;

/**
 * This class defines all the HTTP request handlers regarding individual actions.
 */
public class ActionResource extends ServerResource {
	// DATA FIELDS
	protected Action action;
	protected String Id = null;	// The sequence of characters that identifies the resource.

	/**
	 * Gets the predefined actionId from the URI
	 */
	@Override
	protected void doInit() throws ResourceException
	{
		// Get the "actionId" attribute value taken from the URI template /actions/{actionId}.
		this.Id = (String)getRequest().getAttributes().get("actionId");
	}
	
	/**
	 * Handles GET requests.  Retrieves an Action from the database at {actionId}
	 *
	 * @returns a JSON representation of the requested resource, if it exists;
	 * 			otherwise, returns a JSONMessageResponse with details.
	 * @see aperturescience.types.JSONMessageResponse
	 */
	@Get("JSON")
	public JsonRepresentation getAction()
	{
		DatabaseResource db = new DatabaseResource(WarGamesApplication.couchdburl, WarGamesApplication.databasename);
		try {
			action = db.getAction(Id);
			if(action == null) {
				return JSONMessageResponse.generateMessageRep("500", "?");
			}
			return action.getJsonRepresentation();
		} catch (ResourceException e) {
			return JSONMessageResponse.generateMessageRep("404", "Action[" + Id + "] not found.");
		}
	}
	
	/**
	 * Handles PUT requests; First tries to create an action at {actionId}; 
	 * if there already exists an entry, update the existing entry with the data
	 * given. 
	 *
	 * @param entity	A representation of the resource to be updated.
	 * @returns JSONMessageResponse
	 */
	@Put
	public JsonRepresentation putAction(Representation entity) {
		//create is primary, update is secondary
		DatabaseResource db = new DatabaseResource(
				WarGamesApplication.couchdburl,
				WarGamesApplication.databasename);
		Action action = null;
		
		try {
			action = new Action(entity);
		} catch (JSONException e) {
			return JSONMessageResponse.generateMessageRep(400, "Invalid input to create action.");
		} catch (IOException e) {
			return JSONMessageResponse.generateMessageRep(500, "Communication error");
		}
		
		try {
			if (db.createAction(action, Id))
				return JSONMessageResponse.generateMessageRep(201, Id);
			else
				return JSONMessageResponse.generateMessageRep(500, "Action not created");
		} catch (ResourceException e)	{
			//if we decide to ONLY [CREATE] on PUT, do not comment next line, otherwise, it will bounce down to update.
			//return JSONMessageResponse.generateMessageRep(409, "Action already exists");
		}
		try {
			if (db.updateAction(action, Id))
				return JSONMessageResponse.generateMessageRep(200, Id);
			else
				return JSONMessageResponse.generateMessageRep(500, "Action not updated");
		} catch (ResourceException e) {
			return JSONMessageResponse.generateMessageRep(500, "Unknown failure...");
		}
	}
    
	/**
	 * Handles POST requests; Updates an Action resource in the database at {actionId}.
	 * If no entry exists, it attempts to create one.
	 *
	 * @param entity A representation of the action to be updated.
	 * @returns JSONMessageResponse with details.
	 * @see aperturescience.types.JSONMessageResponse
	 */
	@Post
	public JsonRepresentation postAction(Representation entity) {
		//update is primary, create is secondary
		DatabaseResource db = new DatabaseResource(
				WarGamesApplication.couchdburl,
				WarGamesApplication.databasename);
		Action action = null;
		
		try {
			action = new Action(entity);
		} catch (JSONException e) {
			return JSONMessageResponse.generateMessageRep(400, "Invalid action data.");
		} catch (IOException e) {
			return JSONMessageResponse.generateMessageRep(500, "Communication error");
		}
		
		if( db.getAction(Id) != null )
			if (db.updateAction(action, Id))
				return JSONMessageResponse.generateMessageRep(200, Id);
			else
				return JSONMessageResponse.generateMessageRep(500, "Action not updated");
		//else return JSONMessageResponse.generateMessageRep(404, "Action does not exist");
		else
			if (db.createAction(action, Id))
				return JSONMessageResponse.generateMessageRep(201, Id);
			else
				return JSONMessageResponse.generateMessageRep(500, "Action not created");
	}
	
	/**
	 * Handles DELETE requests; removes a Action resource from the database at {actionId}
	 *
	 * @returns JSONMessageResponse with details on success/failure.
	 * @see aperturescience.types.JSONMessageResponse
	 */
	@Delete
	public JsonRepresentation deleteAction()
	throws IOException {
		DatabaseResource db = new DatabaseResource(WarGamesApplication.couchdburl, WarGamesApplication.databasename);
		if ( db.deleteAction(Id) )
			return JSONMessageResponse.generateMessageRep(200, "Action[" + Id + "] deleted.");
		else
			return JSONMessageResponse.generateMessageRep(404, "Action[" + Id + "] not found.");
	}
}
